Supongamos que queremos construir una lista para almacenar números enteros, pero de modo que siempre esté ordenada de menor a mayor. Para hacer la prueba añadiremos los valores 20, 10, 40, 30. De este modo tendremos todos los casos posibles. Al comenzar, el primer elemento se introducirá en una lista vacía, el segundo se insertará en la primera posición, el tercero en la última, y el último en una posición intermedia.
Insertar un elemento en una lista vacía es equivalente a insertarlo en la primera posición. De modo que no incluiremos una función para asignar un elemento en una lista vacía, y haremos que la función para insertar en la primera posición nos sirva para ese caso también.
void Insertar(Lista *lista, int v) { pNodo nuevo, anterior; /* Crear un nodo nuevo */ nuevo = (pNodo)malloc(sizeof(tipoNodo)); nuevo->valor = v; /* Si la lista está vacía */ if(ListaVacia(*lista) || (*lista)->valor > v) { /* Añadimos la lista a continuación del nuevo nodo */ nuevo->siguiente = *lista; /* Ahora, el comienzo de nuestra lista es en nuevo nodo */ *lista = nuevo; } else { /* Buscar el nodo de valor menor a v */ anterior = *lista; /* Avanzamos hasta el último elemento o hasta que el siguiente tenga un valor mayor que v */ while(anterior->siguiente && anterior->siguiente->valor <= v) anterior = anterior->siguiente; /* Insertamos el nuevo nodo después del nodo anterior */ nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } }
Después probaremos la función para buscar y borrar, borraremos los elementos 10, 15, 45, 30 y 40, así probaremos los casos de borrar el primero, el último y un caso intermedio o dos nodos que no existan.
Recordemos que para eliminar un nodo necesitamos disponer de un puntero al nodo anterior.
void Borrar(Lista *lista, int v) { pNodo anterior, nodo; nodo = *lista; anterior = NULL; while(nodo && nodo->valor < v) { anterior = nodo; nodo = nodo->siguiente; } if(!nodo || nodo->valor != v) return; else { /* Borrar el nodo */ if(!anterior) /* Primer elemento */ *lista = nodo->siguiente; else /* un elemento cualquiera */ anterior->siguiente = nodo->siguiente; free(nodo); } }
#include <stdlib.h> #include <stdio.h> typedef struct _nodo { int valor; struct _nodo *siguiente; } tipoNodo; typedef tipoNodo *pNodo; typedef tipoNodo *Lista; /* Funciones con listas: */ void Insertar(Lista *l, int v); void Borrar(Lista *l, int v); int ListaVacia(Lista l); void BorrarLista(Lista *); void MostrarLista(Lista l); int main() { Lista lista = NULL; pNodo p; Insertar(&lista, 20); Insertar(&lista, 10); Insertar(&lista, 40); Insertar(&lista, 30); MostrarLista(lista); Borrar(&lista, 10); Borrar(&lista, 15); Borrar(&lista, 45); Borrar(&lista, 30); Borrar(&lista, 40); MostrarLista(lista); BorrarLista(&lista); getchar(); return 0; } void Insertar(Lista *lista, int v) { pNodo nuevo, anterior; /* Crear un nodo nuevo */ nuevo = (pNodo)malloc(sizeof(tipoNodo)); nuevo->valor = v; /* Si la lista está vacía */ if(ListaVacia(*lista) || (*lista)->valor > v) { /* Añadimos la lista a continuación del nuevo nodo */ nuevo->siguiente = *lista; /* Ahora, el comienzo de nuestra lista es en nuevo nodo */ *lista = nuevo; } else { /* Buscar el nodo de valor menor a v */ anterior = *lista; /* Avanzamos hasta el último elemento o hasta que el siguiente tenga un valor mayor que v */ while(anterior->siguiente && anterior->siguiente->valor <= v) anterior = anterior->siguiente; /* Insertamos el nuevo nodo después del nodo anterior */ nuevo->siguiente = anterior->siguiente; anterior->siguiente = nuevo; } } void Borrar(Lista *lista, int v) { pNodo anterior, nodo; nodo = *lista; anterior = NULL; while(nodo && nodo->valor < v) { anterior = nodo; nodo = nodo->siguiente; } if(!nodo || nodo->valor != v) return; else { /* Borrar el nodo */ if(!anterior) /* Primer elemento */ *lista = nodo->siguiente; else /* un elemento cualquiera */ anterior->siguiente = nodo->siguiente; free(nodo); } } int ListaVacia(Lista lista) { return (lista == NULL); } void BorrarLista(Lista *lista) { pNodo nodo; while(*lista) { nodo = *lista; *lista = nodo->siguiente; free(nodo); } } void MostrarLista(Lista lista) { pNodo nodo = lista; if(ListaVacia(lista)) printf("Lista vacía\n"); else { while(nodo) { printf("%d -> ", nodo->valor); nodo = nodo->siguiente; } printf("\n"); } }
© Abril de 2001 Salvador Pozo, salvador@conclase.net